<?php

class AppTools {

    const SERVER_TIMEZONE = 'America/Denver'; //hostmonster.com
    const TIMEZONE = 'Asia/Ulaanbaatar';
    //image directories
    const PRODUCT_IMAGE_PATH_ORIG = '/photo/original/';
    const PRODUCT_IMAGE_PATH_THUMB = '/photo/thumb/';
    const PRODUCT_IMAGE_SIZE = 680;
    const PRODUCT_IMAGE_THUMB = 360;
    const DEFAULT_PER_PAGE = 20;

    public static function getFullUrl() {
        $https = !empty($_SERVER['HTTPS']) && strcasecmp($_SERVER['HTTPS'], 'on') === 0;
        return
                ($https ? 'https://' : 'http://') .
                (!empty($_SERVER['REMOTE_USER']) ? $_SERVER['REMOTE_USER'] . '@' : '') .
                (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : ($_SERVER['SERVER_NAME'] .
                        ($https && $_SERVER['SERVER_PORT'] === 443 ||
                        $_SERVER['SERVER_PORT'] === 80 ? '' : ':' . $_SERVER['SERVER_PORT']))) .
                substr($_SERVER['SCRIPT_NAME'], 0, strrpos($_SERVER['SCRIPT_NAME'], '/'));
    }

    public static function getFileNameHash($fileName) {
        return md5(self::getFileName($fileName) . time()) . '.' . AppTools::getFileExtension($fileName);
    }

    public static function getFileName($fileName) {
        return substr($fileName, strrpos($fileName, '/') + 1, strlen($fileName) - strrpos($fileName, '/'));
    }

    public static function getFileExtension($fileName) {
        return strtolower(substr(strrchr($fileName, '.'), 1));
    }

    /**
     * Unique number
     *
     * @return int
     */
    public static function uniqueNumber() {
        list($usec, $sec) = explode(' ', microtime());
        $seed = (float) $sec + ((float) $usec * 100000);

        mt_srand($seed);
        return mt_rand();
    }

    public static function utf8_substr($str, $from, $len) {
# utf8 substr
        return preg_replace('#^(?:[\x00-\x7F]|[\xC0-\xFF][\x80-\xBF]+){0,' . $from . '}' .
                '((?:[\x00-\x7F]|[\xC0-\xFF][\x80-\xBF]+){0,' . $len . '}).*#s', '$1', $str);
    }

    public static function toString($v) {
        return self::cp1251_utf8(trim($v));
    }

    public static function cp1251_utf8($word) {

        $cyr_lower_chars = array(
            'е', 'щ', 'ф', 'ц', 'у', 'ж', 'э',
            'н', 'г', 'ш', 'ү', 'з', 'к', 'ъ',
            'й', 'ы', 'б', 'ө', 'а', 'х', 'р',
            'о', 'л', 'д', 'п', 'я', 'ч', 'ё',
            'с', 'м', 'и', 'т', 'ь', 'в', 'ю',);

        $latin_lower_chars = array(
            'å', 'ù', 'ô', 'ö', 'ó', 'æ', 'ý',
            'í', 'ã', 'ø', '¿', 'ç', 'ê', 'ú',
            'é', 'û', 'á', 'º', 'à', 'õ', 'ð',
            'î', 'ë', 'ä', 'ï', 'ÿ', '÷', '¸',
            'ñ', 'ì', 'è', 'ò', 'ü', 'â', 'þ',);

        $cyr_upper_chars = array(
            'Е', 'Щ', 'Ф', 'Ц', 'У', 'Ж', 'Э',
            'Н', 'Г', 'Ш', 'Ү', 'З', 'К', 'Ъ',
            'Й', 'Ы', 'Б', 'Ө', 'А', 'Х', 'Р',
            'О', 'Л', 'Д', 'П', 'Я', 'Ч', 'Ё',
            'С', 'М', 'И', 'Т', 'Ь', 'В', 'Ю',);

        $latin_upper_chars = array(
            'Å', 'Ù', 'Ô', 'Ö', 'Ó', 'Æ', 'Ý',
            'Í', 'Ã', 'Ø', '¯', 'Ç', 'Ê', 'Ú',
            'É', 'Û', 'Á', 'ª', 'À', 'Õ', 'Ð',
            'Î', 'Ë', 'Ä', 'Ï', 'ß', '×', '¨',
            'Ñ', 'Ì', 'È', 'Ò', 'Ü', 'Â', 'Þ',);

//replacing lower cyrillic
        $word = str_replace($latin_lower_chars, $cyr_lower_chars, $word);
//replacing upper cyrillic
        $word = str_replace($latin_upper_chars, $cyr_upper_chars, $word);

        return $word;
    }

    public static function validateDate($date, $format = 'Y-m-d') {
        $d = DateTime::createFromFormat($format, $date);
        return $d && $d->format($format) == $date;
    }

    public static function datetimeToDate($datetime) {
        return date_format(date_create_from_format('Y-m-d H:i:s', $datetime), 'Y-m-d');
    }

    public static function getDbTime() {
        return UserTable::getMysqlNow();
    }

    public static function convertTimezone($datefield) {
        if (AppTools::validateDate($datefield, 'Y-m-d H:i:s') || AppTools::validateDate($datefield, 'Y-m-d')) {
            $datefield = "'$datefield'";
        }
        if ($_SERVER['SERVER_ADDR'] == '127.0.0.1') {
            return $datefield;
        } else {
            $sql = "CONVERT_TZ($datefield, '" . self::SERVER_TIMEZONE . "',  '" . self::TIMEZONE . "')";
            return $sql;
        }
    }

    public static function getDatesFromInterval($dateBegin, $dateEnd) {
        if (!self::validateDate($dateBegin) || !self::validateDate($dateEnd)) {
            return false;
        }

        $period = new DatePeriod(
                new DateTime("$dateBegin 00:00:00"), new DateInterval('P1D'), new DateTime("$dateEnd 23:59:59")
        );
        $array = array();
        foreach ($period as $date) {
            $array[] = $date->format('Y-m-d');
        }
        return $array;
    }

    private static function _treeNode($cur) {
        $cur['children'] = array();
        return $cur;
    }

    private static function _flatter($node, $parentIdx) {
        //Create an array element of the node
        $array_element = $node;
        //Children are unnecessary
        unset($array_element['children']);
        //Add all children after me
        $result = array($array_element);
        foreach ($node['children'] as $child) {
            $result = array_merge($result, self::_flatter($child, $parentIdx));
        }
        return $result;
    }

    /**
     * 
     * @param array $array An array to be sorted
     * @param string $parentIdx How you're indexing your array's parent node
     * @return array
     */
    public static function sortTreeArray($array, $parentIdx = 'parent_id') {
        $tree = self::_treeNode(array()); //root node                                                     
        $map = array(0 => &$tree);
        foreach ($array as $cur) {
            $map[$cur['id']] = &$map[$cur[$parentIdx]]['children'][];
            $map[$cur['id']] = self::_treeNode($cur);
        }
        //Now recursively flatten the tree:                                                          
        $array = self::_flatter($tree, $parentIdx);
        array_shift($array); //Remove the root node, which was only added as a helper

        return $array;
    }

    public static function buildTreeFromArray($array, $idx = 'id', $parentIdx = 'parent_id') {
        $tree = self::_treeNode(array()); //root node                                                     
        $map = array(0 => &$tree);
        foreach ($array as $cur) {
            $map[$cur[$idx]] = &$map[$cur[$parentIdx]]['children'][];
            $map[$cur[$idx]] = self::_treeNode($cur);
        }

        return $tree['children'];
    }

}

?>